<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<svg width="960" height="600"></svg>

    <script src="./assets/static/d3/d3.v5.js" type="text/javascript"></script>

<script type="text/javascript">
	
	var colors = d3.scaleOrdinal(d3.schemeCategory10);

    var svg = d3.select("svg"),
        width = +svg.attr("width"),
        height = +svg.attr("height"),
        node,
        link;

    svg.append('defs').append('marker')
        .attr('id','arrowhead')
        .attr('viewBox','-0 -5 10 10')
        .attr('refX',13).attr('refY',0)
        .attr('orient','auto')
        .attr('markerWidth',13)
        .attr('markerHeight',13).attr('xoverflow','visible')
        .append('svg:path')
        .attr('d', 'M 0,-5 L 10 ,0 L 0,5')
        .attr('fill', '#999')
        .style('stroke','none');
    var simulation = d3.forceSimulation()
        .force("link", d3.forceLink().id(function (d) {return d.id;}).distance(100).strength(1))
        .force("charge", d3.forceManyBody())
        .force("center", d3.forceCenter(width / 2, height / 2));

    var simulation = d3.forceSimulation()
        .force("link", d3.forceLink().id(function (d) {return d.id;}).distance(100).strength(1))
        .force("charge", d3.forceManyBody())
        .force("center", d3.forceCenter(width / 2, height / 2));


    function update(links, nodes) {
        link = svg.selectAll(".link")
            .data(links)
            .enter()
            .append("line")
            .style("stroke","#999").style("stroke-opacity",".6").style("stroke-width","1px")
            //.attr("class", "link")
            .attr('marker-end','url(#arrowhead)')
        link.append("title")
            .text(function (d) {return d.data.edgeLabel;});

        edgepaths = svg.selectAll(".edgepath")
            .data(links)
            .enter()
            .append('path')
            .attr('class', 'edgepath')
            .attr('fill-opacity', 0)
            .attr('stroke-opacity', 0)
            .attr('id', function (d, i) {return 'edgepath' + i}
            ).style("pointer-events", "none");

        edgelabels = svg.selectAll(".edgelabel")
            .data(links)
            .enter()
            .append('text')
            .style("pointer-events", "none")
            .attr('class', 'edgelabel')
            .attr('id', function (d, i) {return 'edgelabel' + i})
            .attr('font-size', 10)
            .attr('fill', '#aaa');

        edgelabels.append('textPath')
            .attr('xlink:href', function (d, i) {return '#edgepath' + i})
            .style("text-anchor", "middle")
            .style("pointer-events", "none")
            .attr("startOffset", "50%")
            //.text(function (d) {return d.data.edgeLabel});

        node = svg.selectAll(".node")
            .data(nodes)
            .enter()
            .append("g")
            .attr("class", "node")
            .call(d3.drag()
                    .on("start", dragstarted)
                    .on("drag", dragged)
                    //.on("end", dragended)
            );

        node.append("circle")
            .attr("r", 5)
            .style("fill", function (d, i) {return colors(i);})

        /*node.append("title")
            .text(function (d) {return d.id;});

         node.append("text")
            .attr("dy", -3)
            .text(function (d) {return d.data.name;}); */

        simulation
            .nodes(nodes)
            .on("tick", ticked);

        simulation.force("link").links(links);
    }

    function ticked() {
    	console.log("ticked");
        link.attr("x1", function (d) {return d.source.x;})
            .attr("y1", function (d) {return d.source.y;})
            .attr("x2", function (d) {return d.target.x;})
            .attr("y2", function (d) {return d.target.y;});

        node.attr("transform", function (d) {return "translate(" + d.x + ", " + d.y + ")";});

        edgepaths.attr('d', function (d) {
            return 'M ' + d.source.x + ' ' + d.source.y + ' L ' + d.target.x + ' ' + d.target.y;
        });

       edgelabels.attr('transform', function (d) {
          	console.log(d);
            if (d.target.x < d.source.x) {
                var bbox = this.getBBox();
								//console.log(bbox);
                rx = bbox.x + bbox.width / 2;
                ry = bbox.y + bbox.height / 2;
                return 'rotate(180 ' + rx + ' ' + ry + ')';
            }
            else {
                return 'rotate(0)';
            }
        });
    }

    function dragstarted(d) {
    	console.log("dragstarted");
        if (!d3.event.active) simulation.alphaTarget(0.3).restart()
        d.fx = d.x;
        d.fy = d.y;
    }

    function dragged(d) {
        d.fx = d3.event.x;
        d.fy = d3.event.y;
    }

//    function dragended(d) {
//        if (!d3.event.active) simulation.alphaTarget(0);
//        d.fx = undefined;
//        d.fy = undefined;
//    }
  d3.json("HangZhouBank.json").then( function(custRels) {
        var nodeMap = {};
        var graph = {nodes: new Array(custRels.customers.length), links: new Array(custRels.customers.length)};
        for (i=0;i<custRels.customers.length;i++){
        	var node = {
        			id: custRels.customers[i].code,
        			data: custRels.customers[i]
        	}
        	nodeMap[node.id] = node;
        	graph.nodes[i] = node;
        }
        for (i=0;i<custRels.relations.length;i++){
        	var edge = {
        			source: nodeMap[custRels.relations[i].sourceCustomer],
        			target: nodeMap[custRels.relations[i].targetCustomer],
        			data: custRels.relations[i]
        	}
        	graph.links[i] = edge;
        }
        update(graph.links, graph.nodes);
    })


</script>

</body>
</html>